package com.ruoyi.shopping.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.constant.DicConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.coupons.domain.CouponsMember;
import com.ruoyi.shopping.domain.CartVo;
import com.ruoyi.shopping.domain.MallProduct;
import com.ruoyi.shopping.domain.MallProductSpecs;
import com.ruoyi.shopping.service.IMallProductService;
import com.ruoyi.shopping.service.IMallProductSpecsService;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.shopping.mapper.MallCouponsMemberMapper;
import com.ruoyi.shopping.domain.MallCouponsMember;
import com.ruoyi.shopping.service.IMallCouponsMemberService;

/**
 * 优惠券领取Service业务层处理
 *
 * @author ruoyi
 * @date 2022-06-09
 */
@Service
public class MallCouponsMemberServiceImpl implements IMallCouponsMemberService
{
    @Autowired
    private MallCouponsMemberMapper mallCouponsMemberMapper;
    @Autowired
    private IMallProductService productService;
    @Autowired
    private IMallProductSpecsService specsService;

    /**
     * 查询优惠券领取
     *
     * @param id 优惠券领取主键
     * @return 优惠券领取
     */
    @Override
    public MallCouponsMember selectMallCouponsMemberById(Long id)
    {
        return mallCouponsMemberMapper.selectMallCouponsMemberById(id);
    }

    /**
     * 查询优惠券领取列表
     *
     * @param mallCouponsMember 优惠券领取
     * @return 优惠券领取
     */
    @Override
    public List<MallCouponsMember> selectMallCouponsMemberList(MallCouponsMember mallCouponsMember)
    {
        return mallCouponsMemberMapper.selectMallCouponsMemberList(mallCouponsMember);
    }

    /**
     * 新增优惠券领取
     *
     * @param mallCouponsMember 优惠券领取
     * @return 结果
     */
    @Override
    public int insertMallCouponsMember(MallCouponsMember mallCouponsMember)
    {
        mallCouponsMember.setCreateTime(DateUtils.getNowDate());
        return mallCouponsMemberMapper.insertMallCouponsMember(mallCouponsMember);
    }

    /**
     * 修改优惠券领取
     *
     * @param mallCouponsMember 优惠券领取
     * @return 结果
     */
    @Override
    public int updateMallCouponsMember(MallCouponsMember mallCouponsMember)
    {
        mallCouponsMember.setUpdateTime(DateUtils.getNowDate());
        return mallCouponsMemberMapper.updateMallCouponsMember(mallCouponsMember);
    }

    /**
     * 批量删除优惠券领取
     *
     * @param ids 需要删除的优惠券领取主键
     * @return 结果
     */
    @Override
    public int deleteMallCouponsMemberByIds(Long[] ids)
    {
        return mallCouponsMemberMapper.deleteMallCouponsMemberByIds(ids);
    }


    /**
     * 批量逻辑删除优惠券领取
     *
     * @param ids 需要删除的优惠券领取主键
     * @return 结果
     */
    @Override
    public int logicDeleteMallCouponsMember(Long[] ids,String delType,Long delUser)
    {
        return mallCouponsMemberMapper.logicDeleteMallCouponsMember(ids,delType,delUser);
    }

    /**
     * 删除优惠券领取信息
     *
     * @param id 优惠券领取主键
     * @return 结果
     */
    @Override
    public int deleteMallCouponsMemberById(Long id)
    {
        return mallCouponsMemberMapper.deleteMallCouponsMemberById(id);
    }

    @Override
    public List<MallCouponsMember> selectCanUseList(MallCouponsMember cm) {
        return mallCouponsMemberMapper.selectCanUseList(cm);
    }

    @Override
    public List<MallCouponsMember> selectMineCoupons(MallCouponsMember mallCouponsMember) {
        return mallCouponsMemberMapper.selectMineCoupons(mallCouponsMember);
    }

    private void handleGeneral(List<MallCouponsMember> generalList, List<CartVo> cartVos, ArrayList<MallCouponsMember> result) {
        BigDecimal sum = cartVos.stream().map(CartVo::getCountPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        generalList.forEach(e->{
            if(sum.compareTo(e.getMinPrice())>=0){
                result.add(e);
                return;
            }
        });
    }
    @Override
    public List<MallCouponsMember> canUseList(List<CartVo> cartVos,Long loginMemberId) {
        MallCouponsMember mallCouponsMember = new MallCouponsMember();
        mallCouponsMember.setMemberId(loginMemberId);
        mallCouponsMember.setUseState(DicConstants.SYS_N.getCode());
        mallCouponsMember.setCanUseState(DicConstants.SYS_Y.getCode());

        List<Long> specsIds = cartVos.stream().map(CartVo::getSpecsId).collect(Collectors.toList());
        List<Long> productIds = cartVos.stream().map(CartVo::getProductId).collect(Collectors.toList());

        List<MallProduct> products = productService.selectMallProductByIds(productIds);
        List<MallProductSpecs> specsList = specsService.selectListByIds(specsIds);

        cartVos.forEach(cartVo -> {
            specsList.forEach(specs->{
                if(cartVo.getSpecsId().equals(specs.getId())){
                    BigDecimal multiply = specs.getCurrentPrice().multiply(new BigDecimal(cartVo.getCountNum()));
                    cartVo.setCountPrice(multiply);
                    return;
                }
            });
            products.forEach(product->{
                if(cartVo.getProductId().equals(product.getId())){
                    cartVo.setClassifyId(product.getClassifyId());
                    return;
                }
            });
        });
        //区分三种类型
        List<MallCouponsMember> mallCouponsMemberList = this.selectMallCouponsMemberList(mallCouponsMember);
        ArrayList<MallCouponsMember> result = new ArrayList<>();

        List<MallCouponsMember> classifyList = mallCouponsMemberList.stream().filter(e -> DicConstants.COUPON_TYPE_Classify.getCode().equals(e.getCouponType())).collect(Collectors.toList());
        handleClassify(classifyList,cartVos,result);

        List<MallCouponsMember> productList = mallCouponsMemberList.stream().filter(e -> DicConstants.COUPON_TYPE_Product.getCode().equals(e.getCouponType())).collect(Collectors.toList());
        handleProduct(productList,cartVos,result);

        List<MallCouponsMember> generalList = mallCouponsMemberList.stream().filter(e -> DicConstants.COUPON_TYPE_General.getCode().equals(e.getCouponType())).collect(Collectors.toList());
        handleGeneral(generalList,cartVos,result);

        result=result.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<MallCouponsMember>(Comparator.comparing(MallCouponsMember::getId))),ArrayList::new));

        return result;
    }

    @Override
    public List<MallCouponsMember> selectByCouponId(List<Long> collect, Long loginMemberId) {
        if(collect.size()==0) return new ArrayList<MallCouponsMember>();
        return mallCouponsMemberMapper.selectByCouponId(collect,loginMemberId);
    }

    private void handleProduct(List<MallCouponsMember> productList, List<CartVo> cartVos, ArrayList<MallCouponsMember> result) {
        val group = cartVos.stream().collect(Collectors.groupingBy(CartVo::getProductId));
        productList.forEach(e->{
            String[] strings = StringUtils.deleteArrayNull(e.getPrimaryKey().split(","));
            Long[] longs = Arrays.stream(strings)
                    .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()).toArray(new Long[strings.length]);
            for (Long k:group.keySet()) {
                for (int i = 0; i < longs.length; i++) {
                    if (longs[i].equals(k)) {
                        BigDecimal sum = group.get(k).stream().map(CartVo::getCountPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                        if (sum.compareTo(e.getMinPrice()) >= 0) {
                            result.add(e);
                            break;
                        }
                    }
                }
            }
        });
    }

    private void handleClassify(List<MallCouponsMember> classifyList, List<CartVo> cartVos, ArrayList<MallCouponsMember> result) {
        val group = cartVos.stream().collect(Collectors.groupingBy(CartVo::getClassifyId));
        classifyList.forEach(e->{
            String[] strings = StringUtils.deleteArrayNull(e.getPrimaryKey().split(","));
            Long[] longs = Arrays.stream(strings)
                    .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()).toArray(new Long[strings.length]);
            for (Long k:group.keySet()) {
                for (int i = 0; i < longs.length; i++) {
                    if (longs[i].equals(k)) {
                        BigDecimal sum = group.get(k).stream().map(CartVo::getCountPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                        if (sum.compareTo(e.getMinPrice()) >= 0) {
                            result.add(e);
                            break;
                        }
                    }
                }
            }
        });
    }


    @Override
    public List<MallCouponsMember> selectMallCouponsTimeout() {
        return mallCouponsMemberMapper.selectMallCouponsTimeout();
    }
}
